Skip to content

Fix geotiff unbounded allocation DoS and VRT path traversal#1189

Merged
brendancol merged 2 commits intomasterfrom
security-geotiff-1184-1185
Apr 14, 2026
Merged

Fix geotiff unbounded allocation DoS and VRT path traversal#1189
brendancol merged 2 commits intomasterfrom
security-geotiff-1184-1185

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Test plan

  • 11 new tests in test_security.py covering both fixes
  • All 315 existing geotiff tests pass (1 pre-existing matplotlib recursion failure excluded)
  • Verify _check_dimensions rejects oversized allocations and accepts normal ones
  • Verify _read_strips and _read_tiles reject crafted headers with huge dimensions
  • Verify read_to_array passes max_pixels through and normal reads are unaffected
  • Verify VRT relative paths with ../ are canonicalized and no longer contain traversal components
  • Verify VRT absolute paths with ../ are also canonicalized
  • Verify normal relative paths in VRT still resolve correctly

Two security fixes for the geotiff subpackage:

1. Add a configurable max_pixels guard to read_to_array() and all
   internal read functions (_read_strips, _read_tiles, _read_cog_http).
   A crafted TIFF with fabricated header dimensions could previously
   trigger multi-TB allocations. The default limit is 1 billion pixels
   (~4 GB for float32 single-band), overridable via max_pixels kwarg.
   Fixes #1184.

2. Canonicalize VRT source filenames with os.path.realpath() after
   resolving relative paths. Previously, a VRT file with "../" in
   SourceFilename could read arbitrary files outside the VRT directory.
   Fixes #1185.
@github-actions github-actions bot added the performance PR touches performance-sensitive code label Apr 13, 2026
@brendancol brendancol mentioned this pull request Apr 13, 2026
4 tasks
os.path.realpath() converts Unix-style paths to Windows paths on
Windows (e.g. /data/tile.tif becomes D:\data\tile.tif). Use
os.path.realpath() in the assertion so it matches the production
code's canonicalization on all platforms.
@brendancol brendancol merged commit b7e7d1e into master Apr 14, 2026
11 checks passed
brendancol added a commit that referenced this pull request Apr 15, 2026
Resolve add/add conflict in test_security.py by keeping
the GPU-read and VRT allocation guard tests from this branch
alongside the base security tests that landed on master via #1189.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VRT path traversal via ../ in SourceFilename Unbounded allocation from TIFF header dimensions allows memory DoS

1 participant